#region license
/*
 * Copyright (C) 2007 CchenSoft.com
 * 
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License 2.1 or later, as
 * published by the Free Software Foundation. See the included License.txt
 * or http://www.gnu.org/copyleft/lesser.html for details.
 * 
 * Author: Billy Zhang
 */
#endregion

using System.Collections;
using CchenSoft.Workflow.Util;
using CchenSoft.Common.Utils;

public class DefaultVariableResolver : IVariableResolver {
    //~ Static fields/initializers /////////////////////////////////////////////

    //~ Instance fields ////////////////////////////////////////////////////////

    //~ Methods ////////////////////////////////////////////////////////////////

    public object GetVariableFromMaps(string var, IDictionary transientVars) 
    {
        int firstDot = var.IndexOf('.');
        string actualVar = var;

        if (firstDot != -1) {
            actualVar = var.Substring(0, firstDot);
        }

        object o = transientVars[actualVar];

        if (firstDot != -1) {
            o = ReflectUtil.GetProperty(o, var.Substring(firstDot + 1));
        }

        return o;
    }

    /**
       * Parses a string for instances of "${foo}" and returns a string with all instances replaced
       * with the string value of the foo object (<b>foo.toString()</b>). If the string being passed
       * in only refers to a single variable and contains no other characters (for example: ${foo}),
       * then the actual object is returned instead of converting it to a string.
       */
    public object TranslateVariables(string s, IDictionary transientVars) {
        string temp = s.Trim();

        if (temp.StartsWith("${") && temp.EndsWith("}") && (temp.IndexOf('$', 1) == -1)) {
            // the string is just a variable reference, don't convert it to a string
            string var = temp.Substring(2, temp.Length - 1 - 2);

            return GetVariableFromMaps(var, transientVars);
        } else {
            // the string passed in contains multiple variables (or none!) and should be treated as a string
            while (true) {
                int x = s.IndexOf("${");
                int y = (x > -1) ? s.IndexOf("}", x) : -1;

                if ((x != -1) && (y != -1)) {
                    string var = s.Substring(x + 2, y - x - 2);
                    string t = null;
                    object o = GetVariableFromMaps(var, transientVars);

                    if (o != null) {
                        t = o.ToString();
                    }

                    if (t != null) {
                        s = s.Substring(0, x) + t + s.Substring(y + 1);
                    } else {
                        // the variable doesn't exist, so don't display anything
                        s = s.Substring(0, x) + s.Substring(y + 1);
                    }
                } else {
                    break;
                }
            }

            return s;
        }
    }
}
